package com.hp.demo.vteam.base;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.hp.demo.vteam.base.ReflectUtils.LoopHandler;

/**
 * 一个简单的用于将对象转为json字符串的工具方法
 * @author wangre
 */
public class JsonUtil {
	private static final class JsonParseUtils implements LoopHandler
	{
		private StringBuffer bfJson;
		public JsonParseUtils(StringBuffer bfJson)
		{
			this.bfJson = bfJson;
		}

		public void onReadPropertyBegin(Object object, String property) {
			putInAttr(property, this.bfJson);
		}
		
		public void onReadPropertyEnd(Object object, String property) {
			putInValue(object, this.bfJson);
		}

		@Override
		public void begin() {
			this.bfJson.append("{");
		}

		@Override
		public void end() {
			this.bfJson.append("}");
		}
		
		public void onReadPropertySep()
		{
			this.bfJson.append(",");
		}
	}
	/**
	 * 
	 * @param attr
	 * @param buf
	 */
	private static void putInAttr(Object attr,StringBuffer buf)
	{
		buf.append("\"").append(attr.toString()).append("\":");
	}
	
	/**
	 * 
	 * @param value
	 * @param buf
	 */
	private static void putInValue(Object value,StringBuffer buf)
	{
		buf.append("\"").append(value).append("\"");
	}
	
	/**
	 * 
	 * @param objMap
	 * @param bfJson
	 */
	private static void parseMap2Json(Map objMap,StringBuffer bfJson)
	{
		bfJson.append("{");
		Set<Entry> objMapEntries = objMap.entrySet();
		for(Iterator<Entry> entryIterator = objMapEntries.iterator();entryIterator.hasNext();)
		{
			Entry entry = entryIterator.next();
			putInAttr(entry.getKey(),bfJson);
			Object entryValue = entry.getValue();
			if(ReflectUtils.basicType(entryValue))
			{
				putInValue(entryValue,bfJson);
			}
			else
			{
				parse2Json(entryValue,bfJson);
			}
			
			if(entryIterator.hasNext())
			{
				bfJson.append(",");
			}
			else
			{
				break;
			}
		}
		bfJson.append("}");
	}
	
	private static void parseColletion2Json(Collection list,StringBuffer bfJson)
	{
		bfJson.append("[");
		for(Iterator iterator = list.iterator();iterator.hasNext();)
		{
			Object object = iterator.next();
			
			if(ReflectUtils.basicType(object))
			{
				putInValue(object,bfJson);
			}
			else
			{
				parse2Json(object,bfJson);
			}
			
			if(iterator.hasNext())
			{
				bfJson.append(",");
			}
			else
			{
				break;
			}
		}
		bfJson.append("]");
	}
	
	private static void parseArray2Json(Object[] ary,StringBuffer bfJson)
	{
		bfJson.append("[");
		int length = ary.length;
		for(int idx = 0;idx < length ; idx++)
		{
			Object object = ary[idx];
			
			if(ReflectUtils.basicType(object))
			{
				putInValue(object,bfJson);
			}
			else
			{
				parse2Json(object,bfJson);
			}
			
			if(idx < length-1)
			{
				bfJson.append(",");
			}
			else
			{
				break;
			}
		}
		bfJson.append("]");
	}
	
	public static void parse2Json(Object obj,StringBuffer bfJson)
	{
		if(obj instanceof Map)
		{
			parseMap2Json((Map)obj,bfJson);
		}
		else if(obj instanceof Collection)
		{
			parseColletion2Json((Collection) obj,bfJson);
		}
		else if(obj.getClass().isArray())
		{
			parseArray2Json((Object[]) obj, bfJson);
		}
		else
		{
			ReflectUtils.clzBeanAttrLoop(obj, new JsonParseUtils(bfJson));
		}
	}
	
	public static String parse2Json(Object obj)
	{
		StringBuffer bfJson = new StringBuffer();
		parse2Json(obj,bfJson);
		return bfJson.toString();
	}
}
